package semantico;

import analisador.Constants;
import analisador.SemanticError;
import analisador.Token;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import model.ItemTabelaSimbolo;
import model.ItemTemp;
import model.TabelaSimbolo;

public class Semantico implements Constants {

    private String nome;
    private String escopo;
    private String tipo;
    private String modalidade;
    private String modalidadeEsquerda;
    private String modalidadeDireita;
    private String tipoEsquerda;
    private String tipoDireita;
    private String idIndiceVetor;
    private String nomeEsquerda;
    private String nomeDireita;
    private String tipoConstante;
    private boolean inicializada = false;
    private boolean usada = false;
    private String aspecto;
    private List<String> cmd;
    private String chamadaFuncao;
    private String oper;
    private boolean flagExp;
    private int tamVetor;
    private String ladoExp;
    private boolean primeiroOperando;
    private List<ItemTemp> listaTemp;
    private Stack<ItemTemp> pilhaTemp;
    private ItemTemp tmpIdxEsq;
    private ItemTemp tmpAcm;
    private ItemTemp proximoTemp1;
    private ItemTemp proximoTemp2;
    private boolean atribuicao;
    private String oprel;
    private List<ItemTabelaSimbolo> tabelaSimbolo;
    private List<String> rotulos;
    private Stack<String> pilhaRotulo;
    private Stack<String> pilhaFor;
    private String rot;
    private String rot2;
    private String incFor;
    private int contPar;
    private String nomeCall;
    private int posPar;
    
    public Semantico() {
        this.tabelaSimbolo = new ArrayList<ItemTabelaSimbolo>();
        this.cmd = new ArrayList<String>();
        this.listaTemp = new ArrayList<ItemTemp>();
        this.rotulos = new ArrayList<String>();
        this.pilhaRotulo = new Stack<String>();
        this.pilhaTemp = new Stack<ItemTemp>();
        this.pilhaFor = new Stack<String>();
        this.primeiroOperando = true;
        this.nomeCall="";
    }

    public void executeAction(int action, Token token) throws SemanticError {
        switch (action) {
            case 1: {

                nome = token.getLexeme();
                modalidade = "funcao";
                if (buscaNome(nome, escopo) == -1) {
                    insere(nome, escopo);
                } else {
                    throw new SemanticError("Nome já declarado neste escopo: " + token.getLexeme(), token.getPosition());
                }
                geraCod("_"+nome.toUpperCase(),":");
                break;
            }

            case 2: {

                nome = token.getLexeme();
                modalidade = "metodo";
                if (buscaNome(nome, escopo) == -1) {
                    insere(nome, escopo);
                } else {
                    throw new SemanticError("Nome já declarado neste escopo: " + token.getLexeme(), token.getPosition());
                }
                geraCod("_"+nome.toUpperCase(),":");
                break;
            }

            //identificação do main
            case 12: {

                nome = token.getLexeme();
                modalidade = "main";
                tipo = "";
                if (buscaNome(nome, escopo) == -1) {
                    insere(nome, escopo);
                } else {
                    throw new SemanticError("Nome já declarado neste escopo: " + token.getLexeme(), token.getPosition());
                }
                geraCod("_MAIN",":");    
                break;
            }

            //define modalidade parametro
            case 3: {

                nome = token.getLexeme();
                modalidade = "param";
                
                
                if (buscaNome(nome, escopo) == -1) {
                    insere(nome, escopo);
                } else {
                    throw new SemanticError("Nome já declarado neste escopo: " + token.getLexeme(), token.getPosition());
                }
                               
                break;
            }

            //define modalidade variável
            case 4: {

                nome = token.getLexeme();
                modalidade = "var";

                if (buscaNome(nome, escopo) == -1) {
                    insere(nome, escopo);
                } else {
                    throw new SemanticError("Nome já declarado neste escopo: " + token.getLexeme(), token.getPosition());
                }

                break;

            }

            //define variável array
            case 5: {
                nome = token.getLexeme();
                modalidade = "array";
                break;
            }

            //define o escopo program
            case 6: {
                escopo = "program";               
                
                break;
            }

            //busca o escopo
            case 7:
            case 8:
            case 13: {
                escopo = token.getLexeme();
                break;
            }

            case 9: {
                nomeEsquerda = token.getLexeme();
                ladoExp = "esquerdo";

                int pos = buscaNome(nomeEsquerda, escopo);
                
                if (pos == -1) {
                
                    throw new SemanticError("Variável nao declarada neste escopo: " + token.getLexeme(), token.getPosition());
                
                } else {

                    modalidadeEsquerda = this.tabelaSimbolo.get(pos).getModalidade();
                    tipoEsquerda = this.tabelaSimbolo.get(pos).getTipo();
                }

                if ("array".equals(modalidadeEsquerda)) {
                    idIndiceVetor = null;                    
                }              
                
                break;

            }

            case 10: {
                /*
                if (!tipoEsquerda.equals(tipoDireita)) {
                    throw new SemanticError("Tipos incompativeis: " + nomeEsquerda + " | " + tipoConstante, token.getPosition());
                }
                */
                
                if ("array".equals(modalidadeEsquerda) && idIndiceVetor == null) {
                    throw new SemanticError("Array usado sem indice: " + nomeEsquerda, token.getPosition());
                }

                setInicializada(nomeEsquerda, escopo, true);
                setUsada(nomeEsquerda, escopo, false);

                // ATRIBUICAO DA EXPRESSAO A DIREITA NO VETOR
                if ("array".equals(modalidadeEsquerda)) {
                                       
                    geraCod("LD", tmpIdxEsq.getTemp());
                    geraCod("STO", "$indr");
                    geraCod("LD",  tmpAcm.getTemp());
                    geraCod("STOV", escopo + "_" + nomeEsquerda);
                    
                    freeTemp(tmpIdxEsq);
                    freeTemp(tmpAcm);
                                       
                } 
                else if ("array".equals(modalidadeDireita) && "var".equals(modalidadeEsquerda) && contPar==0) {
                                                          
                    geraCod("LD",  tmpAcm.getTemp());
                    geraCod("STO", escopo + "_" + nomeEsquerda);
                    
                    freeTemp(tmpIdxEsq);
                    freeTemp(tmpAcm);
                                       
                }
                else if ("var".equals(modalidadeEsquerda)) {
                    geraCod("STO", escopo + "_" + nomeEsquerda);
                }
                else {
                    if (!flagExp) {
                        if ("constante".equals(aspecto)) {
                            geraCod("STO", escopo + "_" + nomeEsquerda);
                        } else if ("id".equals(aspecto)) {
                            geraCod("STO", escopo + "_" + nomeEsquerda);
                        }

                    } else {
                        if ("+".equals(oper)) {
                            geraCod("ADD", token.getLexeme());
                        } else if ("++".equals(oper)) {
                            geraCod("LD", escopo + "_" + nomeEsquerda);
                            geraCod("ADDI", "1");
                            geraCod("STO", escopo + "_" + nomeEsquerda);
                        } else if ("-".equals(oper)) {
                            geraCod("SUB", token.getLexeme());
                        }
                        flagExp = false;
                    }
                }
                modalidadeEsquerda = "";
                modalidadeDireita = "";
                primeiroOperando = true;
                atribuicao = false;
                flagExp = false;
                break;
            }

            case 11: {

                nomeDireita = token.getLexeme();
                aspecto = "id";
                ladoExp = "direito";

                int pos = buscaNome(nomeDireita, escopo);

                if (pos == -1) {
                    throw new SemanticError("Variável nao declarada neste escopo: " + nomeDireita, token.getPosition());
                }

                if (pos != -1) {
                    modalidadeDireita = this.tabelaSimbolo.get(pos).getModalidade();
                }

                if ((!this.tabelaSimbolo.get(pos).getInicializada())
                        && !this.tabelaSimbolo.get(pos).getModalidade().equals("param")) {

                    throw new SemanticError("Variável nao inicializada: " + nomeDireita, token.getPosition());
                }

                this.setUsada(nomeDireita, escopo, true);

                if ("array".equals(modalidadeEsquerda)&& !"array".equals(modalidadeDireita)) {
                    
                    if (flagExp) {
                        
                        geraCod("LD", tmpAcm.getTemp());
                        
                        if ("+".equals(oper)) {
                            
                            geraCod("ADD", escopo + "_" + nomeDireita);
                            
                        } else if ("-".equals(oper)) {
                            
                            geraCod("SUB", escopo + "_" + nomeDireita);
                            
                        }
                        flagExp = false;                        
                        
                        geraCod("STO", tmpAcm.getTemp());
                        
                    }
                    else{
                        geraCod("LD", escopo + "_" + nomeDireita);                   
                        geraCod("STO", tmpAcm.getTemp());                            
                        setUsada(nomeDireita, escopo, true);
                    }   
                    
                    
                    
                } else if ("var".equals(modalidadeDireita)||"param".equals(modalidadeDireita)) {
                    
                    //geraCod("LD", escopo + "_" + nomeDireita);
                    
                    if (primeiroOperando) {                        
                        
                        geraCod("LD", escopo + "_" + nomeDireita);                                            
                        setUsada(nomeDireita, escopo, true);
                        
                    } else {                                                                       
                                                
                        if ("+".equals(oper)) {
                            geraCod("ADD", escopo + "_" + nomeDireita);
                        } else if ("+".equals(oper)) {
                            geraCod("SUB", escopo + "_" + nomeDireita);
                        }
                    }
                                        
                    //flagExp = false; //aqui                    
                    
                }else if ("param".equals(modalidadeDireita)){
                    
                    geraCod ("LD", escopo + "_" + nomeDireita); // ver se é valor ou id
                    //geraCod ("STO", getParname(nomeDireita, contPar));
                   // contPar++;
                    
                }

                if (!"".equals(nomeCall)&& !"array".equals(modalidadeDireita)){
                    
                    ItemTabelaSimbolo item = getParname(nomeCall, contPar);
                    
                    if (item==null){
                        throw new SemanticError("Quantidade parametro invalida " + nomeCall, token.getPosition());
                    }
                    geraCod ("STO", item.getEscopo()+"_"+item.getNome());
                    contPar++;
                }
                break;
                

            }

            //busca se a função usada foi declarada no escopo do programa
            case 14: {
                nomeDireita = token.getLexeme();

                int pos = buscaNome(nomeDireita, "program");

                if (pos == -1) {
                    throw new SemanticError("Funcao nao declarada no escopo do programa: " + token.getLexeme(), token.getPosition());
                }
                                                
                nomeCall = nomeDireita;
                contPar=0;


                break;

            }

            //obtem o indice do array
            case 15:

                idIndiceVetor = token.getLexeme();

                int pos = buscaNome(idIndiceVetor, escopo);

                if (!idIndiceVetor.matches("[0-9]*") && pos == -1) {
                    throw new SemanticError("Variavel array com indice invalido", token.getPosition());
                }

                if ("array".equals(modalidadeDireita) && idIndiceVetor == null) {
                    throw new SemanticError("Array usado sem indice: " + nomeDireita, token.getPosition());
                }

                if ("esquerdo".equals(ladoExp)) {

                    if (pos != -1) {
                        geraCod("LD", escopo+"_"+this.tabelaSimbolo.get(pos).getNome());
                        setUsada(this.tabelaSimbolo.get(pos).getNome(), escopo, true);
                    } else {

                        geraCod("LDI", idIndiceVetor);

                    }
                    
                    tmpIdxEsq = getTemp();
                    tmpAcm = getTemp();
                    
                    geraCod("STO", tmpIdxEsq.getTemp());

                } else {
                    
                    if (primeiroOperando) {
                        if (pos != -1) {
                            
                            geraCod("LD", escopo+"_"+this.tabelaSimbolo.get(pos).getNome());
                            setUsada(this.tabelaSimbolo.get(pos).getNome(), escopo, true);
                            
                        } else {
                            geraCod("LDI", idIndiceVetor);
                        }
                        geraCod("STO", "$indr");
                        geraCod("LDV", escopo + "_" + nomeDireita);
                        
                        if (!"".equals(nomeCall)){
                            
                            ItemTabelaSimbolo item = getParname(nomeCall, contPar);
                    
                            if (item==null){
                                throw new SemanticError("Quantidade parametro invalida " + nomeCall, token.getPosition());
                            }
                            geraCod ("STO", item.getEscopo()+"_"+item.getNome());
                            contPar++;
                        }

                    } else {
                        
                        //geraCod("STO", tmpAcm.getTemp());

                        if (pos != -1) {
                            geraCod("LD", this.tabelaSimbolo.get(pos).getNome());
                            setUsada(this.tabelaSimbolo.get(pos).getNome(), escopo, true);
                            
                        } else {
                            geraCod("LDI", idIndiceVetor);
                        }
                        geraCod("STO", "$indr");
                        geraCod("LDV", escopo + "_" + nomeDireita);                                                
                        
                        if ("+".equals(oper)) {
                            geraCod("ADD", tmpAcm.getTemp());
                        } else if ("+".equals(oper)) {
                            geraCod("SUB", tmpAcm.getTemp());
                        }
                    }
                    
                    if ("".equals(nomeCall)){
                        
                        geraCod("STO", tmpAcm.getTemp());
                        
                    }
                    else{
                        
                    }
                    
                    flagExp = false; //aqui
                }
                break;

            case 16:

                tamVetor = Integer.parseInt(token.getLexeme());
                if (buscaNome(nome, escopo) == -1) {
                    insere(nome, escopo);

                } else {

                    throw new SemanticError("Nome já declarado neste escopo: " + token.getLexeme(), token.getPosition());

                }

                break;

            case 17: {
                oprel = token.getLexeme();
                geraCod("STO", "temp_esq");

                break;
            }

            case 18: {

                geraCod("STO", "temp_dir");
                geraCod("LD", "temp_esq");
                geraCod("SUB", "temp_dir");

                break;
            }

            //fim de comando
            case 999: {

                // atualizaNome(nome, escopo);
                geraData();
                break;
            }

            case 20: {
                tipo = token.getLexeme();
                break;
            }

            case 21: {

                geraCod("LD", "$in_port");

                if (!"array".equals(modalidadeDireita)) {

                    geraCod("STO", escopo + "_" + nomeDireita);
                } else {
                    geraCod("STO", "temp2");
                    geraCod("LD", "temp1");
                    geraCod("STO", "$indr");
                    geraCod("LD", "temp2");
                    geraCod("STOV", escopo + "_" + nomeDireita);
                }

                break;
            }

            case 22: {
                /*
                 if (!"array".equals(modalidadeDireita)) {
                 if ("constante".equals(aspecto)) {
                 geraCod("LDI", token.getLexeme());
                 }
                 }*/
                geraCod("STO", "$out_port");
                break;
            }

            case 30: {

                flagExp = true;
                oper = token.getLexeme();
                
                if ("+".equals(oper)||"-".equals(oper)){
                    primeiroOperando = false;
                }

                break;
            }

            case 31: {

                atribuicao = true;

                break;
            }

            case 32: {
                rot = this.getNewRotulo();
                this.pilhaRotulo.push(rot);

                if (">".equals(oprel)) {
                    geraCod("BLE", rot);
                } else if ("<".equals(oprel)) {
                    geraCod("BGE", rot);
                } else if (">=".equals(oprel)) {
                    geraCod("BLT", rot);
                } else if ("<=".equals(oprel)) {
                    geraCod("BGT", rot);
                } else if ("==".equals(oprel)) {
                    geraCod("BNE", rot);
                } else if ("!=".equals(oprel)) {
                    geraCod("BEQ", rot);
                }
                break;
            }

            case 33: {
                rot = getNewRotulo();
                rot2 = this.pilhaRotulo.pop();
                geraCod("JMP", rot);
                this.pilhaRotulo.push(rot);
                geraCod(rot2, ":");

                break;
            }
            case 34: {

                rot2 = this.pilhaRotulo.pop();
                geraCod(rot2, ":");

                break;
            }

            case 35: {
                rot = getNewRotulo();
                this.pilhaRotulo.push(rot);
                geraCod(rot, ":");

                break;
            }

            case 36: {
                rot2 = getNewRotulo();
                this.pilhaRotulo.push(rot2);

                if (">".equals(oprel)) {
                    geraCod("BLE", rot2);
                } else if ("<".equals(oprel)) {
                    geraCod("BGE", rot2);
                } else if (">=".equals(oprel)) {
                    geraCod("BLT", rot2);
                } else if ("<=".equals(oprel)) {
                    geraCod("BGT", rot2);
                } else if ("==".equals(oprel)) {
                    geraCod("BNE", rot2);
                } else if ("!=".equals(oprel)) {
                    geraCod("BEQ", rot2);
                }

                break;
            }

            case 37: {

                rot2 = this.pilhaRotulo.pop();
                rot = this.pilhaRotulo.pop();
                geraCod("JMP", rot);
                geraCod(rot2, ":");

                break;
            }

            case 38: {
                rot = getNewRotulo();
                this.pilhaRotulo.push(rot);
                geraCod(rot, ":");
                break;
            }

            case 39: {
                rot2 = this.pilhaRotulo.pop();

                if (">".equals(oprel)) {

                    geraCod("BGT", rot2);

                } else if ("<".equals(oprel)) {

                    geraCod("BLT", rot2);

                } else if (">=".equals(oprel)) {

                    geraCod("BGE", rot2);

                } else if ("<=".equals(oprel)) {

                    geraCod("BLE", rot2);

                } else if ("==".equals(oprel)) {

                    geraCod("BEQ", rot2);

                } else if ("!=".equals(oprel)) {
                    geraCod("BNE", rot2);
                }

                break;
            }

            case 40: {
                rot = getNewRotulo();
                this.pilhaRotulo.push(rot);

                geraCod(rot, ":");
                break;
            }
            case 41: {
                rot = this.pilhaRotulo.pop();
                rot2 = getNewRotulo();

                if (">".equals(oprel)) {
                    geraCod("BLE", rot2);
                } else if ("<".equals(oprel)) {
                    geraCod("BGE", rot2);
                } else if (">=".equals(oprel)) {
                    geraCod("BLT", rot2);
                } else if ("<=".equals(oprel)) {
                    geraCod("BGT", rot2);
                } else if ("==".equals(oprel)) {
                    geraCod("BNE", rot2);
                } else if ("!=".equals(oprel)) {
                    geraCod("BEQ", rot2);
                }

                this.pilhaRotulo.push(rot2);
                this.pilhaRotulo.push(rot);
                break;
            }

            case 42: {
                
                incFor = "LD " + escopo + "_" + nomeEsquerda;
                        
                if ("++".equals(oper)) {
                    incFor += "\nADDI 1";
                } else if ("--".equals(oper)) {
                    incFor += "\nSUBI 1";
                }
                
                incFor += "\nSTO " + escopo + "_" + nomeEsquerda;
                flagExp = false;
                this.pilhaFor.push(incFor);
                break;
            }
            case 43: {
                incFor = this.pilhaFor.pop();
                geraCod(incFor, ""); //variavel que tem o conteudo da ação 20
                rot = this.pilhaRotulo.pop();
                rot2 = this.pilhaRotulo.pop();

                geraCod("JMP", rot);
                geraCod(rot2, ":");

                break;
            }
            
            case 44:{
                
                
                geraCod("RETURN","0");
                break;
            }
            
            case 45:{
                
                geraCod("CALL","_" +nomeCall.toUpperCase());
                nomeCall="";
                break;
            }
            
            case 46:{                
                posPar = 0;
                break;
            }
            
            case 47:{              
                
                geraCod("HLT","0");
                break;
            }
            case 101: {
                tipoConstante = "int";
                aspecto = "constante";
                
                if (!flagExp) {
                    
                    geraCod("LDI", token.getLexeme());
                    
                } else {
                    if("array".equals(modalidadeEsquerda)){
                        geraCod("LD", tmpAcm.getTemp());
                    }
                    
                    if ("+".equals(oper) || "++".equals(oper)) {
                    
                        geraCod("ADDI", token.getLexeme());
                    
                    } else if ("-".equals(oper) || "--".equals(oper)) {
                    
                        geraCod("SUBI", token.getLexeme());
                    
                    }
                    
                    flagExp = false;
                }
                
                if ("array".equals(modalidadeEsquerda)){
                    geraCod("STO", tmpAcm.getTemp());
                }
                
                if (!"".equals(nomeCall)){
                                        
                    ItemTabelaSimbolo item = getParname(nomeCall, contPar);
                    
                    if (item==null){
                        throw new SemanticError("Quantidade parametro invalida " + nomeCall, token.getPosition());
                    }
                    geraCod ("STO", item.getEscopo()+"_"+item.getNome());
                    contPar++;
                }
                break;
            }
            case 102: {
                tipoConstante = "real";
                for (int i = 0; i < 10; i = i + 1) {

                }
                break;
            }
            case 103: {
                tipoConstante = "bin";
                break;
            }
            case 104: {
                tipoConstante = "hex";
                break;
            }
            case 105: {
                tipoConstante = "str";
                break;
            }
            case 106: {
                tipoConstante = "char";
                break;
            }
            case 107:
            case 108:
            case 109: {
                tipoConstante = "bool";
                break;
            }

        }
        
    }

    public TabelaSimbolo getTabelaSimbolo() {
        return new TabelaSimbolo(this.tabelaSimbolo);
    }

    private int buscaNome(String nome, String escopo) {

        for (int i = 0; i < this.tabelaSimbolo.size(); i++) {
            if (this.tabelaSimbolo.get(i).getNome().equals(nome)
                    && this.tabelaSimbolo.get(i).getEscopo().equals(escopo)) {
                return i;
            }
        }

        return -1;
    }

    private void insere(String nome, String escopo) {
                
        
        ItemTabelaSimbolo novoItem = new ItemTabelaSimbolo(nome, escopo, tipo, modalidade, inicializada, usada, tamVetor, posPar);
        
        if( "param".equals(modalidade)){
            posPar++;
        }
        
        this.tabelaSimbolo.add(novoItem);
    }

    private void atualizaNome(String nome, String _escopo) {
        int pos = buscaNome(nome, _escopo);
        if (pos != -1) {

            this.tabelaSimbolo.get(pos).setTipo(tipo);
            this.tabelaSimbolo.get(pos).setEscopo(escopo);
            this.tabelaSimbolo.get(pos).setModalidade(modalidade);
            this.tabelaSimbolo.get(pos).setInicializada(inicializada);
            this.tabelaSimbolo.get(pos).setUsada(usada);

            tipo = "";
            //escopo = "";
            modalidade = "";
            inicializada = false;
            usada = false;
        }
    }

    private void setEscopo(String nome, String _escopo, String valor) {
        int pos = buscaNome(nome, _escopo);
        if (pos != -1) {
            this.tabelaSimbolo.get(pos).setEscopo(valor);
        }
    }

    private void setUsada(String nome, String escopo, boolean valor) {
        int pos = buscaNome(nome, escopo);
        if (pos != -1) {
            this.tabelaSimbolo.get(pos).setUsada(valor);
        }
    }

    private void setInicializada(String nome, String escopo, boolean valor) {
        int pos = buscaNome(nome, escopo);
        if (pos != -1) {
            this.tabelaSimbolo.get(pos).setInicializada(valor);
        }
    }

    private void setModalidade(String nome, String escopo, String valor) {
        int pos = buscaNome(nome, escopo);
        if (pos != -1) {
            this.tabelaSimbolo.get(pos).setModalidade(valor);
        }
    }

    private void freeTemp(ItemTemp nomeTemp) {

        for (int i = 0; i < this.listaTemp.size(); i++) {
            if (nomeTemp.getTemp().equals(this.listaTemp.get(i).getTemp())) {
                this.listaTemp.get(i).setLivre(true);
            }
        }
    }

    private ItemTemp getTemp() {

        for (int i = 0; i < this.listaTemp.size(); i++) {
            if (this.listaTemp.get(i).isLivre()) {
                this.listaTemp.get(i).setLivre(false);
                return this.listaTemp.get(i);
            }
        }

        ItemTemp temp = new ItemTemp("temp" + (this.listaTemp.size() + 1));
        temp.setLivre(false);
        this.listaTemp.add(temp);
        return temp;
    }

    private void geraCod(String cmd, String valor) {
        
       
        cmd += " " + valor;
       
        System.out.println(cmd);

        this.cmd.add(cmd);
    }

    private void geraData() {

        String valoresArray = "";
        int i = 0;
        this.cmd.add(i++, ".data");

        for (ItemTabelaSimbolo item : this.tabelaSimbolo) {

            if ("var".equals(item.getModalidade())||"param".equals(item.getModalidade())) {
                
                this.cmd.add(i++, item.getEscopo() + "_" + item.getNome() + ": " + "0");
                
            } else if ("array".equals(item.getModalidade())) {

                int j;

                for (j = 0; j < item.getTamVetor(); j++) {
                    valoresArray += "0";

                    if (j < item.getTamVetor() - 1) {

                        valoresArray += ", ";
                    }
                }

                this.cmd.add(i++, item.getEscopo() + "_" + item.getNome() + ": " + valoresArray);
            }
        }
        
         for (ItemTemp item : this.listaTemp){
            
         this.cmd.add(i++, item.getTemp()+": 0");
         }
         
                      
        this.cmd.add(i++, "temp_esq: 0");
        this.cmd.add(i++, "temp_dir: 0");

        this.cmd.add(i++, ".text");
        this.cmd.add(i++, "JMP _MAIN");
        

    }

    public String getCodigo() {
        String codigo = "";
        for (String item : this.cmd) {

            codigo += item + "\n";
        }

        return codigo;
    }

    private String getNewRotulo() {
        String novoRotulo = "";

        novoRotulo = "rot" + (this.rotulos.size() + 1);
        this.rotulos.add(novoRotulo);

        return novoRotulo;
    }

    private ItemTabelaSimbolo getParname(String nomeCall, int _contpar){
        
        for (ItemTabelaSimbolo item : this.tabelaSimbolo) {
            
            if("param".equals(item.getModalidade()) && nomeCall.equals(item.getEscopo()) && _contpar==item.getPosPar()){
                return item;
            }
        }
            
        return null;
    }
}
